Repository navigation
feat(agc): emulate undithered alpha-to-coverage - #3228
Conversation
…erage A pixel shader whose stage info asks for alpha-to-coverage declares SampleMask, starts with every sample covered and, at its MRT0 export, clears the mask when the alpha is below one half or NaN, running with late fragment tests. The shader keeps running, as a zero coverage mask does on the GPU. The flag is part of the static shader identity and of the request serialization, now version 16.
DB_ALPHA_TO_MASK 0xaa01, the enable bit with the four offsets at 2 and no OFFSET_ROUND, reaches the pixel stage, which keeps a pixel when its MRT0 alpha is at least one half. Dithered or rounded settings, and an MRT0 that is missing, swizzled, packed or exported without a floating-point alpha, still throw. God of War Sons of Sparta (PPSA28997) stopped on it a few minutes into play.
The expected rows were measured with Vulkan alpha-to-coverage on a Radeon 660M (gfx1035) under RADV_DEBUG=noatocdithering, which programs DB_ALPHA_TO_MASK 0xaa01: an alpha of at least one half, 2 and +inf keep the pixel; below one half, -0, negatives, -inf and NaN drop it.
|
Thank you for your interest in the project! We are sorry, but we cannot accept more PRs while we work through the existing backlog. This PR has been automatically closed and labeled "intake paused". This is not a judgment of the quality of your changes. |
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
|
Windows run, since the PR has only Linux results. Windows 11 (10.0.26200), WinLibs GCC 15.2.0 r7, Release, NVIDIA RTX 4070 Laptop GPU (driver 616.92), head
|
|
Checked on current main: scoped build and ctest ( Notes, not blocking:
Merging. |
What
God of War Sons of Sparta (PPSA28997) stopped a few minutes into play with
alpha-to-coverage is unsupported (register 0x2dc = 0x0000aa01).DB_ALPHA_TO_MASK = 0xaa01is accepted: the enable bit with the four quad offsets at 2 and noOFFSET_ROUND, the undithered setting radeonsi programs. The following still throw:OFFSET_ROUND;alphaToCoverageflag. Such a variant declaresSampleMaskand starts with every sample covered. At its MRT0 export it writes 0 when the alpha is below one half or NaN, and all ones otherwise. It runs with late fragment tests. The shader keeps running after the export, so later stores still happen, as they do with a zero coverage mask on the GPU.CacheKey) and of the request serialization, now version 16.alphaToCoverageEnableis not used: the NVIDIA driver 615.78.08 dithers single-sample coverage. An alpha of 0.25 writes half the pixels of an RTX 3050 Laptop target.Tested
RADV_DEBUG=noatocdithering, which programsDB_ALPHA_TO_MASK = 0xaa01. I compared the GPU's own Vulkan alpha-to-coverage with this emulation for 16 alpha values: 0, -0, 0.25, the two floats below one half, one half, the two floats above it, 0.75, 1, 2, -1, both infinities and both NaNs. All 16 matched on the 660M, and the emulation gave the same result on the RTX 3050. The rows are pinned intests/execution/AlphaToCoverage.cpp. They are not measured on gfx1013, asTechnicalDebt.mdsays.maind31b57a:ctest752/753 passed on the RTX 3050. The failure isagc_driver_dcc_keys_first_write, which fails onmainon this GPU too. Each commit builds and passes the tests it touches (agc_shader_memory,agc_driver_graphics,agc_driver_dual_source_blend).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code